package com.abcd.godating.repository.mongo;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import com.abcd.godating.domain.BasicProfile;
import com.abcd.godating.domain.MoreProfile;
import com.abcd.godating.domain.Profile;
import com.abcd.godating.service.ProfileService;
import com.mongodb.DB;
import com.mongodb.DBCursor;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;

@Repository
public class ProfileRepository implements ProfileService {
	
	private static final String USER_PROFILE = "userProfile";

	@Autowired
	private MongoTemplate mongoTemplate;


	@Override
	public void saveProfile(long userId, Profile profile) {
		mongoTemplate.save(profile, USER_PROFILE);
	}
	
	
	@Override
	public Collection<BasicProfile> getBasicProfiles(Collection<Long> userIds) {
		Collection<Profile> profiles = mongoTemplate.find(new Query(Criteria.where("userId").in(userIds)), Profile.class, USER_PROFILE);
		
		Collection<BasicProfile> basicProfiles = new ArrayList<BasicProfile>();
		if (profiles != null) {
			for (Profile profile : profiles) {
				basicProfiles.add(profile.getBasicProfile());
			}
		}
		
		return basicProfiles;		
	}
	
	@Override
	public void addPicture(long userId, InputStream in, String newPictureName) {
		// get the DB
		DB db = mongoTemplate.getDb();
		
		// put the image into different bucket (base on the user id)
		GridFS gfsPhoto = new GridFS(db, String.valueOf(userId));
		GridFSInputFile gfsFile = gfsPhoto.createFile(in);
		
		// set a new filename for identify purpose
		// TODO: need to think about the files with same name
		gfsFile.setFilename(newPictureName);

		gfsFile.save();

	}
	
	@Override
	public void removePicture(long userId, String pictureName) {
		DB db = mongoTemplate.getDb();
		GridFS gfsPhoto = new GridFS(db, String.valueOf(userId));
		gfsPhoto.remove(gfsPhoto.findOne(pictureName));

	}
	
	@Override
	public OutputStream getPicture(long userId, String pictureName) {
		DB db = mongoTemplate.getDb();
		GridFS gfsPhoto = new GridFS(db, String.valueOf(userId));
		GridFSDBFile gridFSDBFile = gfsPhoto.findOne(pictureName);
		//imageForOutput.writeTo("C:\\Users\\wangx27\\Pictures\\test.png");
		
		OutputStream out = new ByteArrayOutputStream();
		if (gridFSDBFile != null) {
			try {
				gridFSDBFile.writeTo(out);
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					out.close();
				} catch (IOException e) {
				}
			}
		}

		return out;	
	}
	
	@Override
	public Collection<OutputStream> getPricures(long userId) {
		DB db = mongoTemplate.getDb();
		GridFS gfsPhoto = new GridFS(db, String.valueOf(userId));
		DBCursor cursor = gfsPhoto.getFileList();
		Collection<OutputStream> outputStreamList = new ArrayList<OutputStream>();
		if (cursor != null) {
			while (cursor.hasNext()) {
				GridFSDBFile gridFSDBFile = (GridFSDBFile)cursor.next();
				OutputStream out = new ByteArrayOutputStream();
				try {
					gridFSDBFile.writeTo(out);
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						out.close();
					} catch (IOException e) {
					}
				}
				outputStreamList.add(out);
			}
		}
		
		return outputStreamList;
	}
	
	@Override
	public void saveBasicProfile(long userId, BasicProfile basicProfile) {
		Profile profile = getProfile(userId, userId);
		profile.setBasicProfile(basicProfile);
		saveProfile(userId, profile);
	}

	@Override
	public BasicProfile getBasicProfile(long userId) {
		Profile profile = getProfile(userId, userId);
		return profile.getBasicProfile();
	}
	
	@Override
	public void saveMoreProfile(long userId, MoreProfile moreProfile) {
		Profile profile = getProfile(userId, userId);
		profile.setMoreProfile(moreProfile);
		saveProfile(userId, profile);
	}

	@Override
	public MoreProfile getMoreProfile(long userId) {
		Profile profile = getProfile(userId, userId);
		return profile.getMoreProfile();
	}

	@Override
	public void saveNickName(long userId, String nickName) {
		Profile profile = getProfile(userId, userId);
		profile.setNickname(nickName);
		saveProfile(userId, profile);
	}
	
	@Override
	public String getNickName(long userId) {
		Profile profile = getProfile(userId, userId);
		return profile.getNickname();
	}

	@Override
	public OutputStream getSmallPicture(long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Profile getProfile(long userId) {
		return getProfile(userId, userId);
	}

	
	private Profile getProfile(long userId, long id) {
		Profile profile = mongoTemplate.findById(id, Profile.class, String.valueOf(userId));
		if (profile == null) {
			profile = new Profile();
		}
		
		return profile;
	}	

}
